package com.smalldragon.yml.threadpools;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @author YML
 */
@Configuration
public class SafeThreadPoolConfig {

    @Value("${safe.pool.coreSize:5}")
    private int coreSize;

    @Value("${safe.pool.maxSize:10}")
    private int maxSize;

    @Value("${safe.pool.keepAliveTime:60}")
    private int keepAliveTime;

    @Value("${safe.pool.queueCapacity:100}")
    private int queueCapacity;

    @Value("${safe.pool.threadNamePrefix:safe-pool-}")
    private String threadNamePrefix;

    /**
     * 符合阿里巴巴规范的安全线程池
     * 1. 不使用Executors创建
     * 2. 使用有界队列
     * 3. 明确拒绝策略
     */
    @Bean("CommonThreadPool")
    public ThreadPoolExecutor safeThreadPool() {
        return new ThreadPoolExecutor(
                coreSize,
                maxSize,
                keepAliveTime,
                TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(queueCapacity),
                r -> new Thread(r, threadNamePrefix + r.hashCode()),
                // 四种拒绝策略选择其一：
                // 1. CallerRunsPolicy - 由调用线程处理该任务
                // 2. AbortPolicy - 直接抛出异常(默认)
                // 3. DiscardPolicy - 直接丢弃任务
                // 4. DiscardOldestPolicy - 丢弃队列最前面的任务
                new ThreadPoolExecutor.CallerRunsPolicy());
    }

}
